/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ar.edu.unicen.twitter.suggest.backend.dtos;

import ar.edu.unicen.twitter.suggest.backend.datasources.dao.TwitterDatasetDao;
import ar.edu.unicen.twitter.suggest.commons.dtos.Usuario;
import ar.edu.unicen.twitter.suggest.commons.tools.CollectionsOperations;
import java.io.Serializable;
import java.net.URL;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 *
 * Clase contenedora, posee tres campos, referencias a otros objetos exceptuando
 * por el id, los campos restantes son lazy (pueden no conocerse aun, o bien
 * conocerse pero no haberse recuperado de la BD)
 *
 */
public class UsuarioDatasetProxy extends UsuarioDatasetAbstracto implements Serializable {

    UsuarioDataset usuario = null;
    boolean stateSmall = true;
    TwitterDatasetDao twitterDataset;
    private int followerCount = 0;
    List<TweetApi> tw = null;
    int tweetCount;
    private boolean initialized;

    public UsuarioDatasetProxy(long id2, TwitterDatasetDao twitterDataset) {
        super(id2);
        this.twitterDataset = twitterDataset;
        initialized = false;
    }

    private void checkUsuario(boolean stateSmall) {
        if (usuario == null || (!stateSmall && this.stateSmall)) {
            if (!stateSmall) {
                usuario = twitterDataset.getUsuario(id);
            } else {
                usuario = twitterDataset.getUsuarioSmall(id);
            }
            this.stateSmall = stateSmall;
            if (usuario == null) {
                usuario = new UsuarioDataset(id);
            }
            initialized = true;
        }
    }

    public boolean isInitialized(){
        return initialized;
    }
    public void setUsuarioSmall(UsuarioDataset usuarioSmall) {
        if (stateSmall) {
            usuario = usuarioSmall;
        }
    }

    @Override
    public List<TweetApi> getTweets() {
        return getTw();
    }

    @Override
    public int getFollowsCount() {
        checkUsuario(true);
        return usuario.getFollowsCount();
    }

    @Override
    public int getFollowersCount() {
        checkUsuario(true);
        return usuario.getFollowersCount();
    }

    @Override
    public int getTweetsCount() {
        checkUsuario(true);
        return usuario.getTweetsCount();
    }

    @Override
    public String getScreenName() {
        checkUsuario(true);
        return usuario.getScreenName();
    }

    @Override
    public boolean equals(Object o1) {
        if (o1 instanceof Usuario && id == ((Usuario) o1).getId()) {
            return true;
        }
        return false;
    }

    @Override
    public long getId() {
        return id;
    }

    @Override
    public int hashCode() {
        return Usuario.calculateHashCode(id);
    }

    @Override
    public String toString() {
        return "[" + id + "]" + "(<proxy>):" + getMentions() + "m, " + getScore() + "scm " + getFollowsCount() + "fws, " + getFollowersCount() + "fwrs, ";
    }

    public String getName() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getLocation() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getDescription() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isContributorsEnabled() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public URL getProfileImageURL() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public URL getURL() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isProtected() {
        return false;
    }

    public Date getStatusCreatedAt() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public long getStatusId() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getStatusText() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getStatusSource() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isStatusTruncated() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public long getStatusInReplyToStatusId() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public long getStatusInReplyToUserId() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isStatusFavorited() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getStatusInReplyToScreenName() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getProfileBackgroundColor() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getProfileTextColor() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getProfileLinkColor() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getProfileSidebarFillColor() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getProfileSidebarBorderColor() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getFriendsCount() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Date getCreatedAt() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getFavouritesCount() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getUtcOffset() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getTimeZone() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getProfileBackgroundImageUrl() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isProfileBackgroundTiled() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getLang() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getStatusesCount() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isGeoEnabled() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isVerified() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    void setId(long id) {
        this.id = id;
    }

    List<TweetApi> getTw() {
        checkUsuario(false);
        return usuario.getTw();
    }

    @Override
    public int[] getFollowersShortIds() {
        return twitterDataset.getSeguidores(id);
    }

    @Override
    public int[] getFollowsShortIds() {
        return twitterDataset.getSeguidos(id);
    }

     Collection<Usuario> verificar(Collection<Usuario> usuarios) {
        long[] ids = new long[usuarios.size()];
        int i=0;
        for(Usuario usuario: usuarios)
            ids[i++] = usuario.getId();
        List<UsuarioDataset> verificados = (List<UsuarioDataset>) twitterDataset.getUsuariosSmall(CollectionsOperations.getList(ids));
        int u = 0;
        for(Usuario usuario: usuarios){
            ((UsuarioDatasetProxy)usuario).setUsuarioSmall(verificados.get(u++));
        }
        return usuarios;
    }
    
    @Override
    public Collection<Usuario> getFollowers() {
        int[] ids = getFollowersShortIds();
        Collection<Usuario> result = twitterDataset.getUsuariosLazy(CollectionsOperations.getList(ids));
        return verificar(result);
    }

    @Override
    public Collection<Usuario> getFollows() {
        int[] ids = getFollowsShortIds();
        Collection<Usuario> result = twitterDataset.getUsuariosLazy(CollectionsOperations.getList(ids));
        return verificar(result);
    }

    @Override
    public Set<Integer> getFollowSet() {
        checkUsuario(false);
        return usuario.getFollowSet();
    }

    @Override
    public Set<Integer> getFollowerSet() {
        checkUsuario(false);
        return usuario.getFollowerSet();
    }

    @Override
    public long[] getFollowersIds() {
        checkUsuario(false);
        return usuario.getFollowersIds();
    }

    @Override
    public long[] getFollowsIds() {
        checkUsuario(false);
        return usuario.getFollowsIds();
    }
}
